package fr.xebia.data;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * 
 */
@Entity
@Table(name = "client")
public class Client implements Serializable {

	private static final long serialVersionUID = 1L;

	private Long id;
	private String firstname;
	private String lastname;
	private Adresse adresse;
	private Set<Contract> contracts;

	/**
	 * Gets the adresseId
	 * 
	 * @returns the adresseId
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Long getId() {
		return this.id;
	}

	/**
	 * Sets the adresseId
	 * 
	 * @param the
	 *            adresseId
	 */
	public void setId(Long pId) {
		this.id = pId;
	}

	/**
	 * Gets the adresse
	 * 
	 * @returns the adresse
	 */
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    //JoinColumn(name="adresse_id")
    @PrimaryKeyJoinColumn
    public Adresse getAdresse() {
		return this.adresse;
	}

	/**
	 * Sets the adresse
	 * 
	 * @param the
	 *            adresse
	 */
	public void setAdresse(Adresse pAdresse) {
		this.adresse = pAdresse;
	}

	/**
	 * Gets the firstname
	 * 
	 * @returns the firstname
	 */
	@Column(name = "FIRSTNAME")
	public String getFirstname() {
		return this.firstname;
	}

	/**
	 * Sets the firstname
	 * 
	 * @param the
	 *            firstname
	 */
	public void setFirstname(String pFirstname) {
		this.firstname = pFirstname;
	}

	/**
	 * Gets the lastname
	 * 
	 * @returns the lastname
	 */
	@Column(name = "LASTNAME")
	public String getLastname() {
		return this.lastname;
	}

	/**
	 * Sets the lastname
	 * 
	 * @param the
	 *            lastname
	 */
	public void setLastname(String pLastname) {
		this.lastname = pLastname;
	}

	/**
	 * Gets the list of ClientContract
	 * 
	 * @returns the ClientContract List
	 */
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "CLIENT_CONTRACT",
        joinColumns = @JoinColumn(name="CLIENT_ID"),
        inverseJoinColumns = @JoinColumn(name="CONTRACT_ID")
    )
    public Set<Contract> getContracts() {
		return this.contracts;
	}

	/**
	 * Sets the clientContracts
	 * 
	 * @param the
	 *            clientContracts
	 */
	public void setContracts(Set<Contract> contracts) {
		this.contracts = contracts;
	}

	@Override
	public boolean equals(Object obj) {
		Client otherClient = (Client) obj;
		EqualsBuilder equalsBuilder = new EqualsBuilder();
		equalsBuilder.append(getId(), otherClient.getId());
		equalsBuilder.append(getFirstname(), otherClient.getFirstname());
		equalsBuilder.append(getLastname(), otherClient.getLastname());
		return equalsBuilder.isEquals();
	}

	@Override
	public int hashCode() {
		HashCodeBuilder hashCodeBuilder = new HashCodeBuilder();
		hashCodeBuilder.append(getId());
		hashCodeBuilder.append(getFirstname());
		hashCodeBuilder.append(getLastname());
		return hashCodeBuilder.toHashCode();
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		// buffer.append("Client");
		// buffer.append('\n');
		if (adresse != null) {
			buffer.append("adresse=").append(adresse).append(',');
		}
		buffer.append("firstname=").append(firstname).append(',');
		buffer.append("lastname=").append(lastname).append(',');
		return buffer.toString();
	}
}
